#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const bcrypt = require('bcrypt');
const { UserModel } = require('../src/models');

function usage() {
  console.log('用法: node scripts/batchAddUsers.js <username1> <username2> ...');
  console.log('示例: node scripts/batchAddUsers.js alice bob charlie');
}

function initials(text) {
  const t = String(text || '').trim();
  if (!t) return '?' ;
  const parts = t.split(/\s+|_|-/).filter(Boolean);
  if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
  return t.slice(0, 2).toUpperCase();
}

function pickBg(text) {
  const h = crypto.createHash('sha256').update(text).digest();
  const hue = Math.floor(h[0] / 255 * 360);
  const sat = 70; // 70%
  const light = 55; // 55%
  return `hsl(${hue}, ${sat}%, ${light}%)`;
}

function buildSvg(text, size = 128) {
  const init = initials(text);
  const bg = pickBg(text);
  const radius = Math.floor(size / 2);
  const fontSize = Math.floor(size * 0.5);
  return `<?xml version="1.0" encoding="UTF-8"?>\n` +
    `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">\n` +
    `  <circle cx="${radius}" cy="${radius}" r="${radius}" fill="${bg}"/>\n` +
    `  <text x="50%" y="50%" fill="#fff" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial" font-size="${fontSize}" font-weight="700" text-anchor="middle" dominant-baseline="central">${init}</text>\n` +
    `</svg>\n`;
}

function generatePassword(length = 16) {
  const lower = 'abcdefghijklmnopqrstuvwxyz';
  const upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  const digits = '0123456789';
  const symbols = '!@#$%^&*()-_=+[]{};:,.<>/?';
  const all = lower + upper + digits + symbols;
  const pick = set => set[crypto.randomInt(0, set.length)];
  const required = [pick(lower), pick(upper), pick(digits), pick(symbols)];
  const result = [...required];
  while (result.length < length) result.push(pick(all));
  for (let i = result.length - 1; i > 0; i--) {
    const j = crypto.randomInt(0, i + 1);
    [result[i], result[j]] = [result[j], result[i]];
  }
  return result.join('');
}

async function addOne(username) {
  const existed = await UserModel.getUserByUsername(username);
  if (existed) {
    return { username, skipped: true, reason: 'exists', id: existed.id, avatar: existed.avatar || null };
  }
  const password = generatePassword(8);
  const hash = await bcrypt.hash(password, 10);
  const uploadsDir = path.join(__dirname, '..', 'uploads');
  if (!fs.existsSync(uploadsDir)) fs.mkdirSync(uploadsDir, { recursive: true });
  const fname = `avatar-${Date.now()}-${crypto.randomInt(0, 1e9)}.svg`;
  const fpath = path.join(uploadsDir, fname);
  fs.writeFileSync(fpath, buildSvg(username, 128), 'utf8');
  const avatarUrl = `/uploads/${fname}`;
  const id = await UserModel.createUser({
    username,
    password: hash,
    nickname: username,
    avatar: avatarUrl,
    type: 2,
    organization_id: 1
  });
  return { username, id, password, avatar: avatarUrl };
}

async function main() {
  const usernames = process.argv.slice(2);
  if (!usernames.length || usernames.includes('--help')) {
    usage();
    process.exit(usernames.includes('--help') ? 0 : 1);
  }
  const results = [];
  for (const u of usernames) {
    try {
      const r = await addOne(u);
      results.push(r);
    } catch (e) {
      results.push({ username: u, error: e.message || String(e) });
    }
  }
  console.log(JSON.stringify({ message: '批量处理完成', results }, null, 2));
}

main();